package com.dalonedrau.jogl.opengl.ui.border;

import com.dalonedrau.jogl.engine.GameApplet;
import com.dalonedrau.jogl.engine.GlobalConsts;
import com.dalonedrau.jogl.engine.JOGLErrorHandler;
import com.dalonedrau.jogl.engine.Render;
import com.dalonedrau.jogl.opengl.sprite.BasicSpriteObject;
import com.dalonedrau.jogl.opengl.sprite.GroupOfImages;
import com.dalonedrau.jogl.opengl.sprite.SpriteImageObject;
import com.dalonedrau.jogl.opengl.sprite.SpriteImageObjectFactory;
import com.dalonedrau.vectors.Vector3;

/**
 * A simple border, similar to those found in the early 90's SNES games.
 * @author Donald
 */
public abstract class AbstractFlexibleImageBorder extends GuiBorder {
	/**
	 * a bottom-left border image. the left side is a full bar, while the bottom
	 * is a half bar. 8px by 5px.
	 */
	public static final int	BORDER00_BL_LEFT_FULL_BOTTOM_HALF	= 0;
	/**
	 * a bottom-left border image. the left side is a half bar, while the bottom
	 * is a half bar. 5px by 5px.
	 */
	public static final int	BORDER01_BL_LEFT_HALF_BOTTOM_HALF	= 1;
	/**
	 * a bottom-left border image. the left side is a half bar, while the bottom
	 * is a full bar. 5px by 8px.
	 */
	public static final int	BORDER02_BL_LEFT_HALF_BOTTOM_FULL	= 2;
	/**
	 * a bottom-left border image. the left side is a full bar, while the bottom
	 * is a full bar. 8px by 8px.
	 */
	public static final int	BORDER03_BL_LEFT_FULL_BOTTOM_FULL	= 3;
	/**
	 * a bottom-right border image. the right side is a full bar, while the
	 * bottom is a half bar. 8px by 5px.
	 */
	public static final int	BORDER04_BR_RIGHT_FULL_BOTTOM_HALF	= 4;
	/**
	 * a bottom-right border image. the right side is a half bar, while the
	 * bottom is a half bar. 5px by 5px.
	 */
	public static final int	BORDER05_BR_RIGHT_HALF_BOTTOM_HALF	= 5;
	/**
	 * a bottom-right border image. the right side is a half bar, while the
	 * bottom is a full bar. 5px by 8px.
	 */
	public static final int	BORDER06_BR_RIGHT_HALF_BOTTOM_FULL	= 6;
	/**
	 * a bottom-right border image. the right side is a full bar, while the
	 * bottom is a full bar. 8px by 8px.
	 */
	public static final int	BORDER07_BR_RIGHT_FULL_BOTTOM_FULL	= 7;
	/**
	 * a bottom border image. the bottom is a half bar. 1px by 5px.
	 */
	public static final int	BORDER08_B_BOTTOM_HALF				= 8;
	/**
	 * a bottom border image. the bottom is a full bar. 1px by 8px.
	 */
	public static final int	BORDER09_B_BOTTOM_FULL				= 9;
	/**
	 * a top-left border image. the left side is a full bar, while the top is a
	 * half bar. 8px by 5px.
	 */
	public static final int	BORDER10_TL_LEFT_FULL_TOP_HALF		= 10;
	/**
	 * a top-left border image. the left side is a half bar, while the top is a
	 * half bar. 5px by 5px.
	 */
	public static final int	BORDER11_TL_LEFT_HALF_TOP_HALF		= 11;
	/**
	 * a top-left border image. the left side is a half bar, while the top is a
	 * full bar. 5px by 8px.
	 */
	public static final int	BORDER12_TL_LEFT_HALF_TOP_FULL		= 12;
	/**
	 * a top-left border image. the left side is a full bar, while the top is a
	 * full bar. 8px by 8px.
	 */
	public static final int	BORDER13_TL_LEFT_FULL_TOP_FULL		= 13;
	/**
	 * a top-right border image. the right side is a full bar, while the top is
	 * a half bar. 8px by 5px.
	 */
	public static final int	BORDER14_TR_RIGHT_FULL_TOP_HALF		= 14;
	/**
	 * a top-right border image. the right side is a half bar, while the top is
	 * a half bar. 5px by 5px.
	 */
	public static final int	BORDER15_TR_RIGHT_HALF_TOP_HALF		= 15;
	/**
	 * a top-right border image. the right side is a half bar, while the top is
	 * a full bar. 5px by 8px.
	 */
	public static final int	BORDER16_TR_RIGHT_HALF_TOP_FULL		= 16;
	/**
	 * a top-right border image. the right side is a full bar, while the top is
	 * a full bar. 8px by 8px.
	 */
	public static final int	BORDER17_TR_RIGHT_FULL_TOP_FULL		= 17;
	/**
	 * a top border image. the top is a half bar. 1px by 5px.
	 */
	public static final int	BORDER18_T_TOP_HALF					= 18;
	/**
	 * a top border image. the top is a full bar. 1px by 8px.
	 */
	public static final int	BORDER19_T_TOP_FULL					= 19;
	/**
	 * a left border image. the left is a half bar. 5px by 1px.
	 */
	public static final int	BORDER20_L_LEFT_HALF				= 20;
	/**
	 * a left border image. the left is a full bar. 8px by 1px.
	 */
	public static final int	BORDER21_L_LEFT_FULL				= 21;
	/**
	 * a right border image. the right is a half bar. 5px by 1px.
	 */
	public static final int	BORDER22_R_RIGHT_HALF				= 22;
	/**
	 * a right border image. the right is a full bar. 8px by 1px.
	 */
	public static final int	BORDER23_R_RIGHT_FULL				= 23;
	/** the list of images used to render the borders. */
	private String[]		borderImages;
	/** the border group. */
	private GroupOfImages	borders;
	/** the image ref ids used for the borders. */
	private int[]			ids;
	/** Creates a new instance of {@link AbstractFlexibleImageBorder}. */
	public AbstractFlexibleImageBorder(final int[] images, final int[] insets) {
		ids = images;
		super.setInsets(
				insets[0],
				insets[1],
				insets[2],
				insets[GlobalConsts.INT_003]
				);
	}
	/**
	 * Creates a new instance of {@link AbstractFlexibleImageBorder}.
	 * @param images the list of images used to render the border's corners
	 * @param borders the list of corner types used
	 */
	protected AbstractFlexibleImageBorder(final String[] images,
			final int... borders) {
		borderImages = images;
		ids = new int[GlobalConsts.INT_008];
		int insetTop = 0, insetLeft = 0, insetBottom = 0, insetRight = 0;
		try {
			int corner = 0;
			// bottom-left
			switch (borders[corner]) {
			case BORDER00_BL_LEFT_FULL_BOTTOM_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER00_BL_LEFT_FULL_BOTTOM_HALF]
												);
				insetLeft =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER00_BL_LEFT_FULL_BOTTOM_HALF])
								.getWidth();
				insetBottom =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER00_BL_LEFT_FULL_BOTTOM_HALF])
								.getHeight();
				break;
			case BORDER01_BL_LEFT_HALF_BOTTOM_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER01_BL_LEFT_HALF_BOTTOM_HALF]
							);
				insetLeft =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER01_BL_LEFT_HALF_BOTTOM_HALF])
								.getWidth();
				insetBottom =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER01_BL_LEFT_HALF_BOTTOM_HALF])
								.getHeight();
				break;
			case BORDER02_BL_LEFT_HALF_BOTTOM_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER02_BL_LEFT_HALF_BOTTOM_FULL]
							);
				insetLeft =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER02_BL_LEFT_HALF_BOTTOM_FULL])
								.getWidth();
				insetBottom =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER02_BL_LEFT_HALF_BOTTOM_FULL])
								.getHeight();
				break;
			case BORDER03_BL_LEFT_FULL_BOTTOM_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER03_BL_LEFT_FULL_BOTTOM_FULL]
							);
				insetLeft =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER03_BL_LEFT_FULL_BOTTOM_FULL])
								.getWidth();
				insetBottom =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER03_BL_LEFT_FULL_BOTTOM_FULL])
								.getHeight();
				break;
			default:
				GameApplet.getInstance().fatalError(
							new Exception("Value out of bounds: "
									+ borders[corner]));
			}
			corner++;
			// bottom-right
			switch (borders[corner]) {
			case BORDER04_BR_RIGHT_FULL_BOTTOM_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER04_BR_RIGHT_FULL_BOTTOM_HALF]
							);
				insetRight =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER04_BR_RIGHT_FULL_BOTTOM_HALF])
								.getWidth();
				insetBottom =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER04_BR_RIGHT_FULL_BOTTOM_HALF])
								.getHeight();
				break;
			case BORDER05_BR_RIGHT_HALF_BOTTOM_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER05_BR_RIGHT_HALF_BOTTOM_HALF]
							);
				insetRight =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER05_BR_RIGHT_HALF_BOTTOM_HALF])
								.getWidth();
				insetBottom =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER05_BR_RIGHT_HALF_BOTTOM_HALF])
								.getHeight();
				break;
			case BORDER06_BR_RIGHT_HALF_BOTTOM_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER06_BR_RIGHT_HALF_BOTTOM_FULL]
							);
				insetRight =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER06_BR_RIGHT_HALF_BOTTOM_FULL])
								.getWidth();
				insetBottom =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER06_BR_RIGHT_HALF_BOTTOM_FULL])
								.getHeight();
				break;
			case BORDER07_BR_RIGHT_FULL_BOTTOM_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER07_BR_RIGHT_FULL_BOTTOM_FULL]
							);
				insetRight =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER07_BR_RIGHT_FULL_BOTTOM_FULL])
								.getWidth();
				insetBottom =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER07_BR_RIGHT_FULL_BOTTOM_FULL])
								.getHeight();
				break;
			default:
				GameApplet.getInstance().fatalError(
						new Exception("Value out of bounds: "
								+ borders[corner]));
			}
			corner++;
			// bottom
			switch (borders[corner]) {
			case BORDER08_B_BOTTOM_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER08_B_BOTTOM_HALF]
							);
				insetBottom =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER08_B_BOTTOM_HALF])
								.getHeight();
				break;
			case BORDER09_B_BOTTOM_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER09_B_BOTTOM_FULL]
							);
				insetBottom =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER09_B_BOTTOM_FULL])
								.getHeight();
				break;
			default:
				GameApplet.getInstance().fatalError(
						new Exception("Value out of bounds: "
								+ borders[corner]));
			}
			corner++;
			// top-left
			switch (borders[corner]) {
			case BORDER10_TL_LEFT_FULL_TOP_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER10_TL_LEFT_FULL_TOP_HALF]
							);
				insetLeft =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER10_TL_LEFT_FULL_TOP_HALF])
								.getWidth();
				insetTop =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER10_TL_LEFT_FULL_TOP_HALF])
								.getHeight();
				break;
			case BORDER11_TL_LEFT_HALF_TOP_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER11_TL_LEFT_HALF_TOP_HALF]
							);
				insetLeft =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER11_TL_LEFT_HALF_TOP_HALF])
								.getWidth();
				insetTop =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER11_TL_LEFT_HALF_TOP_HALF])
								.getHeight();
				break;
			case BORDER12_TL_LEFT_HALF_TOP_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER12_TL_LEFT_HALF_TOP_FULL]
							);
				insetLeft =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER12_TL_LEFT_HALF_TOP_FULL])
								.getWidth();
				insetTop =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER12_TL_LEFT_HALF_TOP_FULL])
								.getHeight();
				break;
			case BORDER13_TL_LEFT_FULL_TOP_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER13_TL_LEFT_FULL_TOP_FULL]
							);
				insetLeft =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER13_TL_LEFT_FULL_TOP_FULL])
								.getWidth();
				insetTop =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER13_TL_LEFT_FULL_TOP_FULL])
								.getHeight();
				break;
			default:
				GameApplet.getInstance().fatalError(
						new Exception("Value out of bounds: "
								+ borders[corner]));
			}
			corner++;
			// top-right
			switch (borders[corner]) {
			case BORDER14_TR_RIGHT_FULL_TOP_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER14_TR_RIGHT_FULL_TOP_HALF]
							);
				insetRight =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER14_TR_RIGHT_FULL_TOP_HALF])
								.getWidth();
				insetTop =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER14_TR_RIGHT_FULL_TOP_HALF])
								.getHeight();
				break;
			case BORDER15_TR_RIGHT_HALF_TOP_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER15_TR_RIGHT_HALF_TOP_HALF]
							);
				insetRight =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER15_TR_RIGHT_HALF_TOP_HALF])
								.getWidth();
				insetTop =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER15_TR_RIGHT_HALF_TOP_HALF])
								.getHeight();
				break;
			case BORDER16_TR_RIGHT_HALF_TOP_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER16_TR_RIGHT_HALF_TOP_FULL]
							);
				insetRight =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER16_TR_RIGHT_HALF_TOP_FULL])
								.getWidth();
				insetTop =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER16_TR_RIGHT_HALF_TOP_FULL])
								.getHeight();
				break;
			case BORDER17_TR_RIGHT_FULL_TOP_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER17_TR_RIGHT_FULL_TOP_FULL]
							);
				insetRight =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER17_TR_RIGHT_FULL_TOP_FULL])
								.getWidth();
				insetTop =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER17_TR_RIGHT_FULL_TOP_FULL])
								.getHeight();
				break;
			default:
				GameApplet.getInstance().fatalError(
						new Exception("Value out of bounds: "
								+ borders[corner]));
			}
			corner++;
			// top
			switch (borders[corner]) {
			case BORDER18_T_TOP_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER18_T_TOP_HALF]
							);
				insetTop =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER18_T_TOP_HALF])
								.getHeight();
				break;
			case BORDER19_T_TOP_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER19_T_TOP_FULL]
							);
				insetTop =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER19_T_TOP_FULL])
								.getHeight();
				break;
			default:
				GameApplet.getInstance().fatalError(
						new Exception("Value out of bounds: "
								+ borders[corner]));
			}
			corner++;
			// left
			switch (borders[corner]) {
			case BORDER20_L_LEFT_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER20_L_LEFT_HALF]
							);
				insetLeft =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER20_L_LEFT_HALF])
								.getWidth();
				break;
			case BORDER21_L_LEFT_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER21_L_LEFT_FULL]
							);
				insetLeft =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER21_L_LEFT_FULL])
								.getWidth();
				break;
			default:
				GameApplet.getInstance().fatalError(
						new Exception("Value out of bounds: "
								+ borders[corner]));
			}
			corner++;
			// right
			switch (borders[corner]) {
			case BORDER22_R_RIGHT_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER22_R_RIGHT_HALF]
							);
				insetRight =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER22_R_RIGHT_HALF])
								.getWidth();
				break;
			case BORDER23_R_RIGHT_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER23_R_RIGHT_FULL]
							);
				insetRight =
						SpriteImageObjectFactory
								.getInstance()
								.getImageByName(
										borderImages[AbstractFlexibleImageBorder.BORDER23_R_RIGHT_FULL])
								.getWidth();
				break;
			default:
				GameApplet.getInstance().fatalError(
						new Exception("Value out of bounds: "
								+ borders[corner]));
			}

			// set insets
			super.setInsets(
					insetTop,
					insetLeft,
					insetBottom,
					insetRight
					);
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/**
	 * Creates a new instance of {@link AbstractFlexibleImageBorder}.
	 * @param images the list of images used to render the border's corners
	 * @param borders the list of corner types used
	 */
	protected AbstractFlexibleImageBorder(final String[] images,
			final int[] borders, final int[] insets) {
		borderImages = images;
		ids = new int[GlobalConsts.INT_008];
		try {
			int corner = 0;
			// bottom-left
			switch (borders[corner]) {
			case BORDER00_BL_LEFT_FULL_BOTTOM_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER00_BL_LEFT_FULL_BOTTOM_HALF]
												);
				break;
			case BORDER01_BL_LEFT_HALF_BOTTOM_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER01_BL_LEFT_HALF_BOTTOM_HALF]
							);
				break;
			case BORDER02_BL_LEFT_HALF_BOTTOM_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER02_BL_LEFT_HALF_BOTTOM_FULL]
							);
				break;
			case BORDER03_BL_LEFT_FULL_BOTTOM_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER03_BL_LEFT_FULL_BOTTOM_FULL]
							);
				break;
			default:
				GameApplet.getInstance().fatalError(
							new Exception("Value out of bounds: "
									+ borders[corner]));
			}
			corner++;
			// bottom-right
			switch (borders[corner]) {
			case BORDER04_BR_RIGHT_FULL_BOTTOM_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER04_BR_RIGHT_FULL_BOTTOM_HALF]
							);
				break;
			case BORDER05_BR_RIGHT_HALF_BOTTOM_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER05_BR_RIGHT_HALF_BOTTOM_HALF]
							);
				break;
			case BORDER06_BR_RIGHT_HALF_BOTTOM_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER06_BR_RIGHT_HALF_BOTTOM_FULL]
							);
				break;
			case BORDER07_BR_RIGHT_FULL_BOTTOM_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER07_BR_RIGHT_FULL_BOTTOM_FULL]
							);
				break;
			default:
				GameApplet.getInstance().fatalError(
						new Exception("Value out of bounds: "
								+ borders[corner]));
			}
			corner++;
			// bottom
			switch (borders[corner]) {
			case BORDER08_B_BOTTOM_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER08_B_BOTTOM_HALF]
							);
				break;
			case BORDER09_B_BOTTOM_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER09_B_BOTTOM_FULL]
							);
				break;
			default:
				GameApplet.getInstance().fatalError(
						new Exception("Value out of bounds: "
								+ borders[corner]));
			}
			corner++;
			// top-left
			switch (borders[corner]) {
			case BORDER10_TL_LEFT_FULL_TOP_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER10_TL_LEFT_FULL_TOP_HALF]
							);
				break;
			case BORDER11_TL_LEFT_HALF_TOP_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER11_TL_LEFT_HALF_TOP_HALF]
							);
				break;
			case BORDER12_TL_LEFT_HALF_TOP_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER12_TL_LEFT_HALF_TOP_FULL]
							);
				break;
			case BORDER13_TL_LEFT_FULL_TOP_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER13_TL_LEFT_FULL_TOP_FULL]
							);
				break;
			default:
				GameApplet.getInstance().fatalError(
						new Exception("Value out of bounds: "
								+ borders[corner]));
			}
			corner++;
			// top-right
			switch (borders[corner]) {
			case BORDER14_TR_RIGHT_FULL_TOP_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER14_TR_RIGHT_FULL_TOP_HALF]
							);
				break;
			case BORDER15_TR_RIGHT_HALF_TOP_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER15_TR_RIGHT_HALF_TOP_HALF]
							);
				break;
			case BORDER16_TR_RIGHT_HALF_TOP_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER16_TR_RIGHT_HALF_TOP_FULL]
							);
				break;
			case BORDER17_TR_RIGHT_FULL_TOP_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER17_TR_RIGHT_FULL_TOP_FULL]
							);
				break;
			default:
				GameApplet.getInstance().fatalError(
						new Exception("Value out of bounds: "
								+ borders[corner]));
			}
			corner++;
			// top
			switch (borders[corner]) {
			case BORDER18_T_TOP_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER18_T_TOP_HALF]
							);
				break;
			case BORDER19_T_TOP_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER19_T_TOP_FULL]
							);
				break;
			default:
				GameApplet.getInstance().fatalError(
						new Exception("Value out of bounds: "
								+ borders[corner]));
			}
			corner++;
			// left
			switch (borders[corner]) {
			case BORDER20_L_LEFT_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER20_L_LEFT_HALF]
							);
				break;
			case BORDER21_L_LEFT_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER21_L_LEFT_FULL]
							);
				break;
			default:
				GameApplet.getInstance().fatalError(
						new Exception("Value out of bounds: "
								+ borders[corner]));
			}
			corner++;
			// right
			switch (borders[corner]) {
			case BORDER22_R_RIGHT_HALF:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER22_R_RIGHT_HALF]
							);
				break;
			case BORDER23_R_RIGHT_FULL:
				ids[corner] = SpriteImageObjectFactory
						.getInstance()
						.getImageRefId(
								borderImages[AbstractFlexibleImageBorder.BORDER23_R_RIGHT_FULL]
							);
				break;
			default:
				GameApplet.getInstance().fatalError(
						new Exception("Value out of bounds: "
								+ borders[corner]));
			}

			// set insets
			super.setInsets(
					insets[0],
					insets[1],
					insets[2],
					insets[GlobalConsts.INT_003]
					);
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/** Positions all sprites for the border. */
	private void positionSprites() {
		if (super.getPosition() != null) {
			borders.setPosition(
					super.getPosition().getX(),
					super.getPosition().getY(),
					super.getPosition().getZ()
					);
			borders.clearFloatStore();
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void prepareForRendering() throws Exception {
		Render.getInstance().registerEntity(borders);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setPosition(final double x, final double y, final double z) {
		super.setPosition(x, y, z);
		positionSprites();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setPreferredSize(final int width, final int height) {
		super.setPreferredSize(width, height);
		try {
			SpriteImageObject imgBL =
					SpriteImageObjectFactory.getInstance().getImageById(
							ids[0]);
			SpriteImageObject imgBR =
					SpriteImageObjectFactory.getInstance().getImageById(
							ids[1]);
			SpriteImageObject imgB =
					SpriteImageObjectFactory.getInstance().getImageById(
							ids[2]);
			SpriteImageObject imgTL =
					SpriteImageObjectFactory.getInstance().getImageById(
							ids[GlobalConsts.INT_003]);
			SpriteImageObject imgTR =
					SpriteImageObjectFactory.getInstance().getImageById(
							ids[GlobalConsts.INT_004]);
			SpriteImageObject imgT =
					SpriteImageObjectFactory.getInstance().getImageById(
							ids[GlobalConsts.INT_005]);
			SpriteImageObject imgL =
					SpriteImageObjectFactory.getInstance().getImageById(
							ids[GlobalConsts.INT_006]);
			SpriteImageObject imgR =
					SpriteImageObjectFactory.getInstance().getImageById(
							ids[GlobalConsts.INT_007]);
			if (borders == null) {
				borders = new GroupOfImages();
				// sprite images don't get set until the preferred size is set
				{ // bottom left
					BasicSpriteObject sb = new BasicSpriteObject();
					sb.setImageRefId(imgBL.getRefId());
					sb.setWidth(imgBL.getWidth());
					sb.setHeight(imgBL.getHeight());
					borders.addImage(sb);
				}
				{ // bottom middle
					BasicSpriteObject sb = new BasicSpriteObject();
					sb.setImageRefId(imgB.getRefId());
					sb.setHeight(imgB.getHeight());
					borders.addImage(sb);
				}
				{ // bottom right
					BasicSpriteObject sb = new BasicSpriteObject();
					sb.setImageRefId(imgBR.getRefId());
					sb.setWidth(imgBR.getWidth());
					sb.setHeight(imgBR.getHeight());
					borders.addImage(sb);
				}
				{ // left
					BasicSpriteObject sb = new BasicSpriteObject();
					sb.setImageRefId(imgL.getRefId());
					sb.setWidth(imgL.getWidth());
					borders.addImage(sb);
				}
				{ // right
					BasicSpriteObject sb = new BasicSpriteObject();
					sb.setImageRefId(imgR.getRefId());
					sb.setWidth(imgR.getWidth());
					borders.addImage(sb);
				}
				{ // top left
					BasicSpriteObject sb = new BasicSpriteObject();
					sb.setImageRefId(imgTL.getRefId());
					sb.setWidth(imgTL.getWidth());
					sb.setHeight(imgTL.getHeight());
					borders.addImage(sb);
				}
				{ // top middle
					BasicSpriteObject sb = new BasicSpriteObject();
					sb.setImageRefId(imgT.getRefId());
					sb.setHeight(imgT.getHeight());
					borders.addImage(sb);
				}
				{ // top right
					BasicSpriteObject sb = new BasicSpriteObject();
					sb.setImageRefId(imgTR.getRefId());
					sb.setWidth(imgTR.getWidth());
					sb.setHeight(imgTR.getHeight());
					borders.addImage(sb);
				}
			}
			// set bottom-left position
			borders.getImage(0).setPosition(new Vector3(0, 0, 0));
			// set bottom position and width
			borders.getImage(1).setWidth(
					width - imgBL.getWidth() - imgBR.getWidth());
			borders.getImage(1).setPosition(
					new Vector3(imgBL.getWidth(), 0, 0));
			// set bottom-right position
			borders.getImage(2).setPosition(new Vector3(
					width - imgBR.getWidth(), 0, 0));
			// set left position and height
			borders.getImage(GlobalConsts.INT_003).setHeight(
					height - imgBL.getHeight() - imgTL.getHeight());
			borders.getImage(GlobalConsts.INT_003).setPosition(
					new Vector3(0, imgBL.getHeight(), 0));
			// set right position and height
			borders.getImage(GlobalConsts.INT_004).setHeight(
					height - imgBR.getHeight() - imgTR.getHeight());
			borders.getImage(GlobalConsts.INT_004).setPosition(
					new Vector3(width - imgR.getWidth(), imgBR.getHeight(), 0));
			// set top-left position
			borders.getImage(GlobalConsts.INT_005).setPosition(
					new Vector3(0, height - imgTL.getHeight(), 0));
			// set top position and width
			borders.getImage(GlobalConsts.INT_006).setWidth(
					width - imgTL.getWidth() - imgTR.getWidth());
			borders.getImage(GlobalConsts.INT_006)
					.setPosition(
							new Vector3(imgTL.getWidth(), height
									- imgT.getHeight(), 0));
			// set top-right position
			borders.getImage(GlobalConsts.INT_007).setPosition(
					new Vector3(width - imgTR.getWidth(),
							height - imgTR.getHeight(), 0));

			positionSprites();
			imgTL = null;
			imgT = null;
			imgTR = null;
			imgL = null;
			imgR = null;
			imgBL = null;
			imgB = null;
			imgBR = null;
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
}
